//
// Created by 周杰 on 2020/2/12.
//

#include "TestGround.h"

const string v_path = "/Volumes/D/study/machinelearning/opencv/testpic/vtest.avi";

void TestGround::test() {
    VideoCapture cap;
    Mat source, image, foreGround, backGround, fgMask;
    //打开视频
    Ptr<BackgroundSubtractor> pBgModel = createBackgroundSubtractorMOG2().dynamicCast<BackgroundSubtractor>();
    cap.open(v_path);

    if (!cap.isOpened()) {
        cout << "open video fail!" << endl;
        return;
    }
    //循环遍历
    for (;;) {
        //获取下一桢图像
        cap >> source;
        //为空跳出视频
        if (source.empty()) {
            break;
        }
        //裁剪处理更快
        resize(source, image, Size(source.cols / 2, source.rows / 2), INTER_LINEAR);
        if (foreGround.empty()) {
            foreGround.create(image.size(), image.type());
        }

        //背景更新
        pBgModel->apply(image, fgMask);

        threshold(fgMask, fgMask, 30, 255, THRESH_BINARY);

        foreGround = Scalar::all(0);

        //处理前景
        image.copyTo(foreGround, fgMask);

        pBgModel->getBackgroundImage(backGround);

        labelTarget(image, fgMask, 10);

        imshow("source", image);
        imshow("background", backGround);
        imshow("foreground", foreGround);
        imshow("foreground mask", fgMask);

        //退出
        char key = waitKey(100);
        if (key == 27) {
            break;
        }
    }
    waitKey();
    destroyAllWindows();
}

int TestGround::labelTarget(Mat &src, Mat &mask, int thresh) {
    Mat seg = mask.clone();
    vector<vector<Point>> cnts;
    findContours(seg, cnts, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    float area;
    Rect rect;
    int count = 0;
    string strcount;
    for (int i = cnts.size() - 1; i >= 0; i--) {
        vector<Point> c = cnts[i];
        area = contourArea(c);
        //如果面积小于阀值则为噪声
        if (area < thresh) {
            continue;
        }
        count++;
        rect = boundingRect(c);

        cout << "count = " << count << " area = " << area <<
             " position: " << rect.x << " " << rect.y << endl;

        //原图中画出矩形
        rectangle(src, rect, Scalar(0, 0, 0xff), 1);

        //写上文字
        stringstream ss;
        ss << count;
        ss >> strcount;
        putText(src, strcount, Point(rect.x, rect.y), HersheyFonts::FONT_HERSHEY_PLAIN, 0.5, Scalar(0, 0xff, 0));
    }
    return count;
}